package com.zygh.coordinatestore.util;

import cn.hutool.core.date.DateUtil;
import com.zygh.coordinatestore.bean.CorrdinateUtils;
import com.zygh.coordinatestore.entity.Equipment;
import com.zygh.coordinatestore.entity.Gps;
import com.zygh.coordinatestore.mapper.EquipmentMapper;
import com.zygh.coordinatestore.mapper.GpsMapper;
import org.postgis.Point;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;


@Component
public class StatisticsServer {
    @Autowired
    private GpsMapper gpsMapper;
    @Autowired
    private EquipmentMapper equipmentMapper;
    //private ExecutorService threadPoolExecutor = new ThreadPoolExecutor(20, Integer.MAX_VALUE, 1, TimeUnit.MINUTES, new SynchronousQueue<Runnable>());
    private Logger logger = LoggerFactory.getLogger( StatisticsServer.class );
    ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();

    {

        //配置核心线程数
        threadPoolExecutor.setCorePoolSize( 10 );
        //配置最大线程数
        threadPoolExecutor.setMaxPoolSize( 80 );
        //配置队列大小
        threadPoolExecutor.setQueueCapacity( 1000 );
        //配置线程池中的线程的名称前缀
        threadPoolExecutor.setThreadNamePrefix( "thread-" );
        // rejection-policy：当pool已经达到max size的时候，如何处理新任务
        // CALLER_RUNS：不在新线程中执行任务，而是有调用者所在的线程来执行
        threadPoolExecutor.setRejectedExecutionHandler( new ThreadPoolExecutor.CallerRunsPolicy() );
        //执行初始化
        threadPoolExecutor.initialize();
    }

    public void doSave( byte[] buf ) throws UnsupportedEncodingException {

        if ( buf == null || buf.length < 1 ) {
            throw new RuntimeException( "接收数据为空" );
        } else {
            if ( (byte) 0xAA != buf[0]
                    || (byte) 0xAA != buf[1] ) {
                throw new RuntimeException( "标志头错误" );
            }
            if ( (byte) 0xCC != buf[2]
                    || (byte) 0xCC != buf[3] ) {
                throw new RuntimeException( "命令字错误" );
            }
            //System.out.println((byte) 0x22+"   "+(byte) 0x00+"   "+bytes[4]+"   "+bytes[5]);
            if ( (byte) 0x22 != buf[5]
                    || (byte) 0x00 != buf[4] ) {
                throw new RuntimeException( "版本号错误" );
            }

        }

        byte[] bodyLength = new byte[4];// new
        byte[] terCode = new byte[20];
        byte[] x = new byte[8];
        byte[] y = new byte[8];

        byte[] year = new byte[2];
        byte[] month = new byte[1];
        byte[] day = new byte[1];
        byte[] hour = new byte[1];
        byte[] min = new byte[1];
        byte[] sec = new byte[1];

        System.arraycopy( buf, 6, bodyLength, 0, 4 );
        System.arraycopy( buf, 10, terCode, 0, 20 );
        System.arraycopy( buf, 30, x, 0, 8 );
        System.arraycopy( buf, 38, y, 0, 8 );

        System.arraycopy( buf, 54, year, 0, 2 );
        System.arraycopy( buf, 56, month, 0, 1 );
        System.arraycopy( buf, 57, day, 0, 1 );
        System.arraycopy( buf, 58, hour, 0, 1 );
        System.arraycopy( buf, 59, min, 0, 1 );
        System.arraycopy( buf, 60, sec, 0, 1 );

        int remarksize = BitConverter.byteArrayToInt( bodyLength ) - 51;
        byte[] remark = new byte[remarksize];
        System.arraycopy( buf, 61, remark, 0, remarksize );
        String gpsid = new String( terCode, "GB2312" ).trim();
        Gps gps = new Gps();
        gps.setGpsid( String.valueOf( gpsid ) );
        gps.setDate( String.valueOf( DateUtil.thisYear() + "-" + ( String.valueOf( month[0] ).length() == 1 ? "0" + month[0] : month[0] ) + "-" + ( String.valueOf( day[0] ).length() == 1 ? "0" + day[0] : day[0] ) + " " + ( String.valueOf( hour[0] ).length() == 1 ? "0" + hour[0] : hour[0] ) + ":" + ( String.valueOf( min[0] ).length() == 1 ? "0" + min[0] : min[0] ) + ":" + ( String.valueOf( sec[0] ).length() == 1 ? "0" + sec[0] : sec[0] ) ) );

        String s = String.valueOf( BitConverter.byteToDouble( x ) );
        String s1 = String.valueOf( BitConverter.byteToDouble( y ) );
        String coord = s + "," + s1;

        try {
            Point point = CorrdinateUtils.formatPoint( coord );
            gps.setGps( point );
            getSec( gps );
        } catch ( Exception e ) {
            e.printStackTrace();
            System.out.println();
        }
    }

    @Async("asyncServiceExecutor")
    public void getSec( Gps gps ) {
        threadPoolExecutor.execute( () -> {

            List<Equipment> equipment = equipmentMapper.findEquipment( String.valueOf( gps.getGpsid() ) );
            if ( !equipment.isEmpty() ) {
                gps.setCode( equipment.get( 0 ).getCallNo() );
            }
            gpsMapper.insertTest( gps );
        } );
    }

}